﻿using System;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Minecraft.Model;
using Minecraft.Model.ReqResp;
using TestClient.Client.Com;
using TestClient.Util;


namespace TestClient
{
    public partial class LoginForm : Form
    {

        #region 构造单例模式,防止出现多个同样窗口

        public static LoginForm instance;

        public static LoginForm CreateForm()
        {
            if (instance == null || instance.IsDisposed)
            {
                instance = new LoginForm();
            }
            return instance;
        }

        #endregion

        public LoginForm()
        {
            InitializeComponent();
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void loginSubmit_button_Click(object sender, EventArgs e)
        {
            var account = account_textBox.Text.Trim();
            var password = password_textBox.Text.Trim();
            if (string.IsNullOrEmpty(account) || string.IsNullOrEmpty(password))
            {
                return;
            }
            //
            //ClientStart.Start();


            //byte[] buffer = System.Text.Encoding.UTF8.GetBytes("xxxxxxxxxxxxxxxxx");

            //ClientStart.ClientSocket.Send(buffer);


            EnumCommand command = EnumCommand.Player_PlayerLogin;

            var req = new PlayerLoginReq()
            {
                PlayerId = 1, // ClientData.PlayerId,
            };

            ////登录
            ComManager.Send(MainForm.ClientSocket, () =>
            {
                return new CommandReq<PlayerLoginReq>
                {
                    Command = command,
                    Req = req
                };
            });
        }



        private static void Send(object o)
        {
            var socketClient = o as Socket;
            //不停的给服务器发送数据
            int i = 0;
            while (true)
            {
                //i++;
                var buffter = Encoding.UTF8.GetBytes($"Test Send Message:{i}");
                var temp = socketClient.Send(buffter);
                Thread.Sleep(1000);



            }
        }

        private static void Receive(object o)
        {
            var socketClient = o as Socket;
            while (true)
            {
                try
                {
                    //获取发送过来的消息
                    byte[] buffer = new byte[1024 * 1024 * 2];
                    var effective = socketClient.Receive(buffer);
                    if (effective == 0)
                    {
                        break;
                    }
                    var str = Encoding.UTF8.GetString(buffer, 0, effective);
                    //黏包情况处理（用结束符分割处理）
                    var strs = str.Split(new String[] { SeparatorConfig.StickyBag }, StringSplitOptions.RemoveEmptyEntries);
                    if (strs.Count() >= 2)
                    {
                        Console.WriteLine("------【出现黏包情况】");
                        foreach (var item in strs)
                        {
                            //获取数据部分
                            var receiveInfo = GetReceiveInfo(item);
                            Opt(socketClient, receiveInfo.data);
                        }
                    }
                    else
                    {
                        //可能出现分包情况，合包处理（本地测试客户端未处理）

                        //缓存数据部分，完成后做拼接，这里先不做处理（先省略掉）
                        var receiveInfo = GetReceiveInfo(strs[0]);
                        Opt(socketClient, receiveInfo.data);
                    }
                }
                catch (InvalidOperationException ex)
                {
                    Thread.Sleep(1000);
                }
                catch (SocketException ex)
                {
                    Console.ForegroundColor = ConsoleColor.Magenta;
                    Console.WriteLine("服务器已经关闭！！！");
                    Console.ResetColor();
                    Thread.Sleep(1000);
                    socketClient.Dispose();
                    socketClient = null;
                    ClientStart.Start(true);
                    break;
                }
                catch (Exception ex)
                {

                    Console.WriteLine("接收异常:" + ex);
                }

                Thread.Sleep(5000);
            }
        }


        private static ReceiveInfo GetReceiveInfo(string str)
        {
            var strs = str.Split(new string[] { SeparatorConfig.DataPacketHead }, StringSplitOptions.RemoveEmptyEntries);
            return new ReceiveInfo
            {
                dataLen = Convert.ToInt32(strs[0]),
                data = strs[1]
            };
        }
        class ReceiveInfo
        {
            public int dataLen { get; set; }
            public string data { get; set; }
        }


        private static void Opt(Socket socketClient, string item)
        {
            var deStr = EncryptHelper.Decrypt(item, "client");
            var deStrs = deStr.Split(new string[] { SeparatorConfig.Transfer }, StringSplitOptions.None);
            var protocolStr = deStrs[0];
            var respStr = string.Join(SeparatorConfig.Transfer, deStrs.Skip(1).ToArray());
            EnumCommand command = ProtocolHelper.GetCommand(protocolStr);
            //▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲输出协议传输信息▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲

            //top_textBox.Text = respStr;
            //Debug.WriteLine(respStr);
            MessageBox.Show(respStr + "\t" + protocolStr.ToString());

            /*
            if (JsonConfig.Value.IsDebug)
            {
                ComManager.ConsoleWriteResp(command, respStr);
            }
            // 加载程序集(dll文件地址)，使用Assembly类
            var execName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, AppDomain.CurrentDomain.FriendlyName);
            Assembly assembly = Assembly.LoadFile(execName);
            string className = "Minecraft.ServerHall.Client.Receive." + command.ToString();
            //获取类型，参数（名称空间+类）   
            Type type = assembly.GetType(className);
            //创建该对象的实例，object类型，参数（名称空间+类）   
            object instance = assembly.CreateInstance(className);
            if (instance == null)
            {
                return;
            }
            //设置Show_Str方法中的参数类型，Type[]类型；如有多个参数可以追加多个   
            Type[] params_type = new Type[3];
            params_type[0] = typeof(Socket);
            params_type[1] = typeof(EnumCommand);
            params_type[2] = typeof(string);
            //设置Show_Str方法中的参数值；如有多个参数可以追加多个   
            Object[] params_obj = new Object[3];
            params_obj[0] = socketClient;
            params_obj[1] = command;
            params_obj[2] = respStr;
            //执行Show_Str方法   
            object value = type.GetMethod("Execute", params_type).Invoke(instance, params_obj);

            */
        }

        /// <summary>
        /// 一
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LoginForm_Load(object sender, EventArgs e)
        {
            account_textBox.Text = "aaa";
            password_textBox.Text = "bbb";

           
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {

        }
    }
}
